home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
editors
/
mjovesrc.zoo
/
insert.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-04
|
16KB
|
824 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
#include "jove.h"
#include "ctype.h"
#include "list.h"
#include "chars.h"
#include "disp.h"
private void
DoNewline proto((bool indentp));
private Bufpos
*lisp_indent proto((void));
/* Make a new line after "after" in buffer "buf", unless "after" is NULL,
in which case we insert the new line before first line. */
Line *
listput(buf, after)
register Buffer *buf;
register Line *after;
{
register Line *newline = nbufline();
newline->l_prev = after;
if (after == NULL) { /* Before the first line */
newline->l_next = buf->b_first;
buf->b_first = newline;
} else {
newline->l_next = after->l_next;
after->l_next = newline;
}
if (newline->l_next != NULL)
newline->l_next->l_prev = newline;
else if (buf != NULL)
buf->b_last = newline;
if (buf && buf->b_dot == NULL)
buf->b_dot = newline;
return newline;
}
/* Divide the current line and move the current line to the next one */
void
LineInsert(num)
register int num;
{
char newline[LBSIZE];
register Line *newdot,
*olddot;
int oldchar;
olddot = curline;
oldchar = curchar;
newdot = curline;
while (--num >= 0) {
newdot = listput(curbuf, newdot);
SavLine(newdot, NullStr);
}
modify();
if (curchar != 0) {
strcpy(newline, &linebuf[curchar]);
linebuf[curchar] = '\0'; /* Shorten this line */
SavLine(curline, linebuf);
strcpy(linebuf, newline);
} else { /* Redisplay optimization */
newdot->l_dline = curline->l_dline;
SavLine(curline, NullStr);
}
makedirty(curline);
curline = newdot;
curchar = 0;
makedirty(curline);
IFixMarks(olddot, oldchar, curline, curchar);
}
/* Inserts tabs and spaces to move the cursor to column GOAL. It
Uses the most optimal number of tabs and spaces no matter what
was there before hand. */
void
n_indent(goal)
register int goal;
{
int dotcol,
incrmt;
DelWtSpace();
dotcol = calc_pos(linebuf, curchar);
for (;;) {
incrmt = (tabstop - (dotcol % tabstop));
if (dotcol + incrmt > goal)
break;
insert_c('\t', 1);
dotcol += incrmt;
}
if (dotcol != goal)
insert_c(' ', (goal - dotcol));
}
#ifdef ABBREV
void
MaybeAbbrevExpand()
{
if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
!bolp() && ismword(linebuf[curchar - 1]))
AbbrevExpand();
}
#endif
private void
Insert(c)
int c;
{
if (c == CTL('J'))
LineInsert(arg_value());
else
insert_c(c, arg_value());
}
void
SelfInsert()
{
#ifdef ABBREV
MaybeAbbrevExpand();
#endif
if (LastKeyStruck != CTL('J') && MinorMode(OverWrite)) {
register int num,
i;
for (i = 0, num = arg_value(); i < num; i++) {
int pos = calc_pos(linebuf, curchar);
if (!eolp()) {
if (linebuf[curchar] == '\t') {
if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
del_char(FORWARD, 1, NO);
} else
del_char(FORWARD, 1, NO);
}
insert_c(LastKeyStruck, 1);
}
} else
Insert(LastKeyStruck);
if (MinorMode(Fill) && (curchar >= RMargin ||
(calc_pos(linebuf, curchar) >= RMargin))) {
int margin;
Bufpos save;
if (MinorMode(Indent)) {
DOTsave(&save);
ToIndent();
margin = calc_pos(linebuf, curchar);
SetDot(&save);
} else
margin = LMargin;
DoJustify(curline, 0, curline,
curchar + (int)strlen(&linebuf[curchar]), YES, margin);
}
}
/* insert character C N times at point */
void
insert_c(c, n)
int c,
n;
{
if (n <= 0)
return;
modify();
makedirty(curline);
ins_c(c, linebuf, curchar, n, LBSIZE);
IFixMarks(curline, curchar, curline, curchar + n);
curchar += n;
}
/* Tab in to the right place for C mode */
void
Tab()
{
#ifdef LISP
if (MajorMode(LISPMODE) && (bolp() || !eolp())) {
int dotchar = curchar;
Mark *m = NULL;
ToIndent();
if (dotchar > curchar)
m = MakeMark(curline, dotchar, M_FLOATER);
(void) lisp_indent();
if (m) {
ToMark(m);
DelMark(m);
} else
ToIndent();
return;
}
#endif
if (MajorMode(CMODE)) {
if (within_indent())
(void) c_indent(NO);
else {
int curpos,
tabbed_pos;
skip_wht_space();
curpos = calc_pos(linebuf, curchar);
tabbed_pos = curpos + (CIndIncrmt - (curpos % CIndIncrmt));
n_indent(tabbed_pos);
}
} else
SelfInsert();
}
void
QuotChar()
{
int c,
slow = NO;
c = waitchar(&slow);
if (c != CTL('@'))
Insert(c);
}
/* Insert the paren. If in C mode and c is a '}' then insert the
'}' in the "right" place for C indentation; that is indented
the same amount as the matching '{' is indented. */
int PDelay = 5, /* 1/2 a second */
CIndIncrmt = 8;
void
DoParen()
{
Bufpos *bp;
int tried = NO,
nx,
c = LastKeyStruck;
if (!jisclosep(c)) {
SelfInsert();
return;
}
if (MajorMode(CMODE) && c == '}' && within_indent()) {
bp = c_indent(YES);
tried = TRUE;
}
#ifdef LISP
if (MajorMode(LISPMODE) && c == ')' && blnkp(linebuf)) {
bp = lisp_indent();
tried = TRUE;
}
#endif
SelfInsert();
#ifdef MAC
if (MinorMode(ShowMatch) && !in_macro()) {
#else
if (MinorMode(ShowMatch) && !charp() && !in_macro()) {
#endif
b_char(1); /* Back onto the ')' */
if (!tried)
bp = m_paren(c, BACKWARD, NO, YES);
f_char(1);
if (bp != NULL) {
nx = in_window(curwind, bp->p_line);
if (nx != -1) { /* is visible */
Bufpos b;
DOTsave(&b);
SetDot(bp);
SitFor(PDelay);
SetDot(&b);
} else
s_mess("%s", lcontents(bp->p_line));
}
mp_error(); /* display error message */
}
}
void
LineAI()
{
DoNewline(TRUE);
}
void
Newline()
{
DoNewline(MinorMode(Indent));
}
private void
DoNewline(indentp)
bool indentp;
{
Bufpos save;
int indent;
/* first we calculate the indent of the current line */
DOTsave(&save);
ToIndent();
indent = calc_pos(linebuf, curchar);
SetDot(&save);
#ifdef ABBREV
MaybeAbbrevExpand();
#endif
if (
#ifdef LISP
MajorMode(LISPMODE) ||
#endif
indentp || blnkp(linebuf))
{
DelWtSpace();
}
/* If there is more than 2 blank lines in a row then don't make
a newline, just move down one. */
if (arg_value() == 1 && eolp() && TwoBlank())
SetLine(curline->l_next);
else
LineInsert(arg_value());
if (indentp) {
#ifdef LISP
if (MajorMode(LISPMODE))
(void) lisp_indent();
else
#endif
{
Bol();
n_indent((LMargin == 0) ? indent : LMargin);
}
}
}
void
ins_str(str, ok_nl)
register char *str;
int ok_nl;
{
register char c;
Bufpos save;
int llen;
if (*str == '\0')
return; /* ain't nothing to insert! */
DOTsave(&save);
llen = strlen(linebuf);
while ((c = *str++) != '\0') {
if (c == '\n' || (ok_nl && llen >= LBSIZE - 2)) {
IFixMarks(save.p_line, save.p_char, curline, curchar);
modify();
makedirty(curline);
LineInsert(1);
DOTsave(&save);
llen = strlen(linebuf);
}
if (c != '\n') {
ins_c(c, linebuf, curchar++, 1, LBSIZE);
llen += 1;
}
}
IFixMarks(save.p_line, save.p_char, curline, curchar);
modify();
makedirty(curline);
}
void
open_lines(n)
int n;
{
Bufpos dot;
DOTsave(&dot);
LineInsert(n); /* Open the lines... */
SetDot(&dot);
}
void
OpenLine()
{
open_lines(arg_value());
}
/* Take the region FLINE/FCHAR to TLINE/TCHAR and insert it at
ATLINE/ATCHAR in WHATBUF. */
Bufpos *
DoYank(fline, fchar, tline, tchar, atline, atchar, whatbuf)
Line *fline,
*tline,
*atline;
int fchar,
tchar,
atchar;
Buffer *whatbuf;
{
register Line *newline;
static Bufpos bp;
char save[LBSIZE],
buf[LBSIZE];
Line *startline = atline;
int startchar = atchar;
lsave();
if (whatbuf)
modify();
(void) ltobuf(atline, genbuf);
strcpy(save, &genbuf[atchar]);
(void) ltobuf(fline, buf);
if (fline == tline)
buf[tchar] = '\0';
linecopy(genbuf, atchar, &buf[fchar]);
atline->l_dline = putline(genbuf);
makedirty(atline);
fline = fline->l_next;
while (fline != tline->l_next) {
newline = listput(whatbuf, atline);
newline->l_dline = fline->